package voip.directory.server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import voip.directory.OPERATIONS;
import voip.directory.Packet;
import voip.directory.User_Entry;


public class DirectoryServer {
	private int port, maxConnections, numConnections;
	ArrayList<User_Entry> user_list;
	
	public static void main(String[] args){
		System.out.println("Creating Server");
		DirectoryServer s = new DirectoryServer(4444,3);
		s.Listen();
	}
	
	public DirectoryServer(int port, int maxConnections){
		this.user_list = new ArrayList<User_Entry>();
		this.port = port;
		this.maxConnections = maxConnections;
	}
	
	// Listen for incoming connections and handle them
	public void Listen() {
		
		try{
			ServerSocket listener = new ServerSocket(this.port);
			
			
			System.out.println("Waiting for Clients...");
			System.out.println("Port: " +listener.getLocalPort());
			System.out.println("Address: " +listener.getInetAddress().getHostAddress());
			System.out.println("Name: " +listener.getInetAddress().getHostName());

			Socket newClient;

			while((numConnections++ < maxConnections) || (maxConnections == 0)){
				System.out.println("IN WAITING LOOP");
				newClient = listener.accept();
				System.out.println("ACCEPTED!!!!!!!");
				Worker_Thread conn_c= new Worker_Thread(newClient,this);
				Thread t = new Thread(conn_c);
				t.start();
			}
		} catch (IOException ioe) {
			System.out.println("IOException on socket listen: " + ioe);
			ioe.printStackTrace();
		}
	}

}

class Worker_Thread implements Runnable {
	private Socket server;
	private DirectoryServer ds;
	private String line,input;

	Worker_Thread(Socket server, DirectoryServer ds) {
		this.server=server;
		this.ds = ds;
	}

	public void run () {
		try {			
			// Get input from the client
			ObjectInputStream in = new ObjectInputStream (server.getInputStream());
			ObjectOutputStream out = new ObjectOutputStream(server.getOutputStream());

			while(true) {
				Packet p = (Packet) in.readObject();
				switch(p.opt){
				case OPERATIONS.INITIAL_ENTRY:
				{
					User_Entry entry = (User_Entry) p.getContents();
					ds.user_list.add(entry);
					break;
				}
					case OPERATIONS.GET_USER_LIST:
					{
						System.out.println("REQUEST FOR USER LIST");
						out.writeObject(ds.user_list);
						out.flush();
						break;
					}
					case OPERATIONS.CLOSE_CONNECTION:
					{
						out.writeObject(ds.user_list);
						out.flush();
						server.close();
						return;
					}
				}

			}


		} catch (IOException ioe) {
			System.out.println("IOException on socket listen: " + ioe);
			ioe.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

